﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Dynamic;
using System.Reflection;

namespace MvcProjectFotos
{
    public class DynamicViewPage : ViewPage
    {
        // Hide the base Model property and replace it with a dynamic one
        public new dynamic Model { get; private set; }

        protected override void SetViewData(ViewDataDictionary viewData)
        {
            base.SetViewData(viewData);

            // Create a dynamic object that can do private reflection over the model object
            Model = new ReflectionDynamicObject() { RealObject = ViewData.Model };
        }

        class ReflectionDynamicObject : DynamicObject
        {
            internal object RealObject { get; set; }

            public override bool TryGetMember(GetMemberBinder binder, out object result)
            {
                // Get the property value
                result = RealObject.GetType().InvokeMember(
                    binder.Name,
                    BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                    null,
                    RealObject,
                    null);

                // Always return true, since InvokeMember would have thrown if something went wrong
                return true;
            }
        }
    }
}